<template>
  <div>
    <!-- 
      git 大小写跟踪问题 输入命令 git config core.ignorecase false

    -->
  </div>
</template>

<script setup lang="ts">
/** emit
 // 子组件 
 // 定义触发的事件及其数据类型
 const emit = defineEmits(['update', 'delete']);
 
 // 触发事件
 const handleUpdate = () => {
   emit('update', { id: 1, name: 'Vue 3' });
 };
 
 // 父组件
 <ChildComponent @update="handleUpdate" @delete="handleDelete" />

 const handleUpdate = (data) => {
  console.log('更新事件触发：', data);
 };

 const handleDelete = (id) => {
   console.log('删除事件触发，ID:', id);
 };
*/

/** props
  // 子组件
  <input :value="value" @input="handleInput" />

  const emit = defineEmits(['input']);
  const props = defineProps({
    value: String
  });

  // 父组件
  const inputValue = ref('初始值');
  <ChildComponent :value="inputValue" @input="handleInput" />

  const handleInput = (value) => {
    inputValue.value = value;
  };

 
 */

/* 
  // 定义 props 类型
  interface Props {
    value: string;
  }

  // 定义 emits 类型
  type Emits = {
    (event: 'input', value: string): void;
    (event: 'delete'): void;
  };

  const props = defineProps<Props>();
  const emit = defineEmits<Emits>();

  // 使用 emit
  const handleInput = (value: string) => {
    emit('input', value);
  };

  const handleDelete = () => {
    emit('delete');
  };


  emit('update-value'); // 推荐
  emit('updateValue'); // 不推荐

  如果需要传递多个参数，建议使用对象，这样更容易扩展和维护。
  emit('update', { id: 1, name: 'Vue 3' }); // 推荐
  emit('update', 1, 'Vue 3'); // 不推荐
*/

/*
 导出数据给父组件
 const childMethod = () => {
  console.log('子组件的方法被调用了');
 };
 defineExpose({
  childMethod
 });
*/

/*
  优雅的请求
  const fetchData = async () => {
    loading.value = true;
    error.value = null;
    try {
      const response = await axios.get("https://api.example.com/data");
      data.value = response.data;
    } catch (err) {
      if (axios.isAxiosError(err)) {
        error.value = err.message;
      } else {
        error.value = "发生了一个未知错误";
      }
    } finally {
      loading.value = false;
    }
  };
 */

/**
  避免改变单向数据流
  
  解决方法：使用一个计算属性

  子组件
  const model = computed({
    get(){
      return new Proxy(props.modelValue, {
        get(target, key, receiver){
          return Reflect.get(target, key, receiver)
        },
        set(target, key, value){
          emit('update:modelValue', { ...target, [key]: value })
        }
      })
    },
    set(){
      emit('update:modelValue', value)
    }
  })

  封装成通用函数
  import { computed } from 'vue'
  export const useVModel = (props, propName, emit) => {
    return computed({
      get(){
        return new Proxy(props[propName], {
          get(target, key, receiver){
            return Reflect.get(target, key, receiver)
          },
          set(target, key, value){
            emit('update:modelValue', { ...target, [key]: value })
            return true
          }
        })
      },
      set(val){
        emit(`update:${propName}`, val)
      }
    })
  }

  子组件直接使用该函数
  const emit = defineEmits(['update:modelValue'])
  const model = useVModel(props, 'modelValue', emit)

*/
</script>

<style scoped></style>
